# -*- coding: utf-8 -*-
import json
import logging

from common.coupon import db
from common.coupon.model import AccountCoupon
from common.notification.handler import notify_verify_successfully
from common.show.model import SHOW_STATUS, AnnounceShow
from common.utils import tracker
from common.utils import tz
from common.utils.api import check_params
from common.utils.decorator import sql_wrapper
from common.utils.exceptions import (ParamError,
                                     ResourceNotFound)
from common.utils.helper import parse_query_dct, generate_filter, get_count, get_orderby, paginate
from common.utils.tz import now_ts

_LOGGER = logging.getLogger('bigbang')

_TIMELINE_SIZE = 10

ROAD_MAP = {
    SHOW_STATUS.WAIT_SHOW: {
        SHOW_STATUS.WAIT_VERIFY: {}
    },
    SHOW_STATUS.WAIT_VERIFY: {
        SHOW_STATUS.VERIFY_SUCCESS: {"flag": {"need_award": False}},
        SHOW_STATUS.VERIFY_FAIL: {"flag": {"push_fail": False}}
    },
    SHOW_STATUS.VERIFY_FAIL: {
        SHOW_STATUS.WAIT_SHOW: {},
        SHOW_STATUS.VERIFY_SUCCESS: {"flag": {"need_award": False}}
    }
}


@sql_wrapper
def get_user_shows(user_id, limit=0, offset=0):
    query = AnnounceShow.query.filter(AnnounceShow.user_id == user_id)
    query = query.order_by(AnnounceShow.status).order_by(
        AnnounceShow.created_at.desc())
    if limit > 0:
        query = query.limit(limit)
    if offset > 0:
        query = query.offset(offset)
    return query.all()


@sql_wrapper
def get_user_verified_shows(user_id, limit=0, offset=0):
    query = AnnounceShow.query.filter(AnnounceShow.user_id == user_id).filter(
        AnnounceShow.status == SHOW_STATUS.VERIFY_SUCCESS)
    query = query.order_by(AnnounceShow.verified_at.desc())
    if limit > 0:
        query = query.limit(limit)
    if offset > 0:
        query = query.offset(offset)
    return query.all()


@sql_wrapper
def get_latest_highlight_shows():
    query = AnnounceShow.query.filter(AnnounceShow.status == SHOW_STATUS.VERIFY_SUCCESS) \
        .filter(AnnounceShow.highlight > 0) \
        .order_by(AnnounceShow.verify_award.desc())
    query = query.order_by(AnnounceShow.verified_at.desc())
    query = query.limit(2)
    return query.all()


@sql_wrapper
def get_verfied_shows(limit=0, offset=0):
    query = AnnounceShow.query.filter(AnnounceShow.status == SHOW_STATUS.VERIFY_SUCCESS)
    query = query.order_by(AnnounceShow.verified_at.desc())
    if limit > 0:
        query = query.limit(limit)
    if offset > 0:
        query = query.offset(offset)
    return query.all()


@sql_wrapper
def get_show_by_id(show_id):
    show = AnnounceShow.query.filter(AnnounceShow.id == show_id).first()
    if not show:
        raise ResourceNotFound('show id not invalid')
    return show


@sql_wrapper
def get_show_by_order_index(order_index_id):
    show = AnnounceShow.query.filter(AnnounceShow.order_id == order_index_id).first()
    if not show:
        raise ResourceNotFound('show id not invalid')
    return show


@sql_wrapper
def update_show(show_id, content, images):
    announce_show = AnnounceShow.query.filter(
        AnnounceShow.id == show_id).one()
    if announce_show.status == SHOW_STATUS.VERIFY_SUCCESS:
        raise ParamError('announce show status invalid')
    announce_show.content = content
    # 处理水印或缩略图
    images = clean_images(images)
    announce_show.images = images
    announce_show.status = SHOW_STATUS.WAIT_VERIFY
    announce_show.save()


def clean_images(images):
    # 处理水印或缩略图后缀
    results = []
    for image in images.split(','):
        results.append(image.split('-')[0])
    return ','.join(results)


@sql_wrapper
def update_mutable(show_id, dct):
    show = AnnounceShow.query.with_for_update().filter(
        AnnounceShow.id == show_id).one()
    for k in dct:
        setattr(show, k, dct[k])
    show.save()


@sql_wrapper
def verify_show(show_id, status, verify_comment, highlight):
    announce_show = AnnounceShow.query.with_for_update().filter(
        AnnounceShow.id == show_id).one()
    old_status = announce_show.status
    if status != old_status:
        if old_status not in ROAD_MAP or status not in ROAD_MAP[old_status]:
            raise ParamError('status %s -> %s not allowed' %
                             (old_status, status))
        announce_show.status = status
    announce_show.verify_comment = verify_comment
    announce_show.highlight = highlight
    announce_show.verified_at = now_ts()
    announce_show.save()
    return announce_show


@sql_wrapper
def create_show(order, activity_type):
    announce_show = AnnounceShow()
    announce_show.term_number = order.term
    announce_show.order_id = order.id
    announce_show.activity_type = activity_type
    announce_show.user_id = order.user_id
    announce_show.status = SHOW_STATUS.WAIT_SHOW

    detail = order.as_dict()
    for k in ('created_at', 'updated_at'):
        if detail[k]:
            detail[k] = tz.utc_to_local_str(detail[k])
    announce_show.detail = json.dumps(detail)
    announce_show.save()


@sql_wrapper
def list_shows(query_dct):
    query_dct = parse_query_dct(query_dct, AnnounceShow)
    query = AnnounceShow.query.filter(generate_filter(query_dct, AnnounceShow))
    total_count = get_count(query)
    orderby = get_orderby(query_dct.get('$orderby'), AnnounceShow)
    if orderby is not None:
        query = query.order_by(orderby)
    query = paginate(query, query_dct)
    return query.all(), total_count
